﻿using Common.Logging;
using NHibernate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Xmart.Action
{
    public class ModelAction : AbstractAction
    {
        public ModelAction(ISessionFactory sessionFactory)
            : base(sessionFactory)
        {
        }

        ILog log = LogManager.GetCurrentClassLogger();

        protected Spring.Data.NHibernate.HibernateTemplate Template { get; set; }

        public override ISessionFactory SessionFactory
        {
            get
            {
                return Template.SessionFactory;
            }
            set
            {
                Template = new Spring.Data.NHibernate.HibernateTemplate(value);
            }
        }

        public IActionResult ExecuteSave(object model)
        {
            log.DebugFormat("ExecuteSave:{0}", model);
            IActionResult result = new ActionResult();

            ExecuteTransaction(result,
                (ar) =>
                {
                    Template.SaveOrUpdate(model);
                }
            );

            return result;
        }

        public IActionResult ExecuteDelete(object model)
        {
            log.DebugFormat("ExecuteDelete:{0}", model);
            IActionResult result = new ActionResult();

            ExecuteTransaction(result,
                (ar) =>
                {
                    Template.Delete(model);
                }
            );

            return result;
        }

        public IActionResult ExecuteQuery(string hql, object[] values)
        {
            log.DebugFormat("ExecuteDelete:{0}");
            IActionResult result = new ActionResult();

            ExecuteQuery(result, (ar) =>
                {
                    ar.Data = Template.Find(hql, values);
                });

            return result;
        }

        public void ExecuteTransaction(IActionResult ar, System.Action<IActionResult> callback)
        {

            using (var session = Template.SessionFactory.OpenSession())
            {
                using (var trans = session.BeginTransaction())
                {
                    try
                    {
                        callback(ar);
                        trans.Commit();
                        ar.Success = true;
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        ar.Success = false;
                        ar.MsgAppendLine(ex.Message);
                        throw;
                    }
                }
            }
        }

        public void ExecuteQuery(IActionResult ar, Action<IActionResult> func)
        {
            try
            {
                func(ar);
                ar.Success = true;
            }
            catch (Exception ex)
            {
                ar.Success = false;
                ar.MsgAppendLine(ex.Message);
                throw;
            }
        }
    }
}
